package com.whmskj.xjlhbc.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whmskj.xjlhbc.core.Page;
import com.whmskj.xjlhbc.domain.CorpMember;
import com.whmskj.xjlhbc.domain.Jx05dStaffIncentiveAndSanctionLo;
import com.whmskj.xjlhbc.dto.JcQueryDto;
import com.whmskj.xjlhbc.mapper.CorpMemberMapper;
import com.whmskj.xjlhbc.mapper.Jx05dStaffIncentiveAndSanctionLoMapper;
import com.whmskj.xjlhbc.service.IJx05dStaffIncentiveAndSanctionLoService;
import com.whmskj.xjlhbc.service.IPersonnelManagementDataSheetsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.stream.Collectors;

@Service
public class Jx05dStaffIncentiveAndSanctionLoServiceImpl
        extends ServiceImpl<Jx05dStaffIncentiveAndSanctionLoMapper, Jx05dStaffIncentiveAndSanctionLo> implements IJx05dStaffIncentiveAndSanctionLoService {

    @Autowired
    private CorpMemberMapper corpMemberMapper;

    @Override
    public List<Jx05dStaffIncentiveAndSanctionLo> queryList(JcQueryDto param) {
        int type = param.getType();
        CorpMember corpMember = getCorpMember();
        if (corpMember == null) {
            return new ArrayList<>();
        }
        String memberId = corpMember.getMemberId();
        Page.startPage();
        List<Jx05dStaffIncentiveAndSanctionLo> list = lambdaQuery()
                .eq(type == 1, Jx05dStaffIncentiveAndSanctionLo::getTheAuthor, memberId)
                .like(StringUtils.hasText(param.getTypeOfAward()), Jx05dStaffIncentiveAndSanctionLo::getTypeOfAward, param.getTypeOfAward())
                .like(StringUtils.hasText(param.getReason()), Jx05dStaffIncentiveAndSanctionLo::getReason, param.getReason())
                .like(StringUtils.hasText(param.getNameworkNumber()), Jx05dStaffIncentiveAndSanctionLo::getNameworkNumber, param.getNameworkNumber())
                .eq(StringUtils.hasText(param.getStatus()), Jx05dStaffIncentiveAndSanctionLo::getStatus, param.getStatus())
                .eq(StringUtils.hasText(param.getWorkshop()), Jx05dStaffIncentiveAndSanctionLo::getWorkshop, param.getWorkshop())
                .eq(StringUtils.hasText(param.getModifyer()), Jx05dStaffIncentiveAndSanctionLo::getModifyer, param.getModifyer())
                .eq(StringUtils.hasText(param.getApprovingOfficer()), Jx05dStaffIncentiveAndSanctionLo::getApprovingOfficer, param.getApprovingOfficer())
                .ge(StringUtils.hasText(param.getStartDate()), Jx05dStaffIncentiveAndSanctionLo::getDateOfRewardAndSanction, param.getStartDate())
                .le(StringUtils.hasText(param.getEndDate()), Jx05dStaffIncentiveAndSanctionLo::getDateOfRewardAndSanction, param.getEndDate())
                .orderByDesc(Jx05dStaffIncentiveAndSanctionLo::getId).list();
        list.forEach(item->{
            // 转换 theAuthor 字段
            String theAuthor = item.getTheAuthor();
            if (StringUtils.hasText(theAuthor)) {
                LambdaQueryWrapper<CorpMember> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(CorpMember::getMemberId, theAuthor).last("limit 1");
                CorpMember member = corpMemberMapper.selectOne(wrapper);
                if (member != null && StringUtils.hasText(member.getNick())) {
                    item.setTheAuthor(member.getNick());
                }
            }

            // 转换 modifyer 字段
            String modifyer = item.getModifyer();
            if (StringUtils.hasText(modifyer)) {
                LambdaQueryWrapper<CorpMember> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(CorpMember::getMemberId, modifyer).last("limit 1");
                CorpMember member = corpMemberMapper.selectOne(wrapper);
                if (member != null && StringUtils.hasText(member.getNick())) {
                    item.setModifyer(member.getNick());
                }
            }
            String approvingOfficer = item.getApprovingOfficer();
            if (StringUtils.hasText(approvingOfficer)) {
                LambdaQueryWrapper<CorpMember> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(CorpMember::getMemberId, approvingOfficer).last("limit 1");
                CorpMember member = corpMemberMapper.selectOne(wrapper);
                if (member != null && StringUtils.hasText(member.getNick())) {
                    item.setApprovingOfficer(member.getNick());
                }
            }
        });
        return list;
    }

    @Override
    public boolean add(Jx05dStaffIncentiveAndSanctionLo body) {
        CorpMember corpMember = getCorpMember();
        if (corpMember == null) {
            return false;
        }
        QueryWrapper<Jx05dStaffIncentiveAndSanctionLo> wrapper = new QueryWrapper<>();
        wrapper.select("ifnull(max(awardTicketNumber+0),'202500000') awardTicketNumber");
        Jx05dStaffIncentiveAndSanctionLo max = getOne(wrapper);
        body.setTheAuthor(corpMember.getMemberId());
        body.setDateOfRewardAndSanction(DateUtil.today());
        body.setNameworkNumber(body.getName());
        body.setTimeOfSubmission(DateUtil.now());
        body.setModifyer(body.getTheAuthor());
        body.setModified(DateUtil.now());
        body.setAwardTicketNumber(max.getAwardTicketNumber()+1);
        body.setAmountStatistical(body.getTypeOfAward().equals("处罚") ? "-"+body.getAmount() : body.getAmount());
        body.setStatus("待审核");
        body.setWorkNumber("001");
        return save(body);
    }

    @Override
    public boolean approve(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }

        List<Jx05dStaffIncentiveAndSanctionLo> list = listByIds(ids);
        list.forEach(item -> {
            item.setStatus("已审核");
            item.setModifyer(getCorpMember().getMemberId());
            item.setModified(DateUtil.now());
            item.setApprovingOfficer(getCorpMember().getMemberId());
            item.setApprovalTime(DateUtil.now());
        });

        return updateBatchById(list);
    }

    @Override
    public boolean invalidate(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }

        List<Jx05dStaffIncentiveAndSanctionLo> list = listByIds(ids);
        list.forEach(item -> {
            item.setStatus("已作废");
            item.setModifyer(StpUtil.getLoginId().toString());
            item.setModified(DateUtil.now());
        });

        return updateBatchById(list);
    }

    @Override
    public Map<String, Object> getCurrentUserStatistics() {
        CorpMember corpMember = getCorpMember();
        if (corpMember == null) {
            Map<String, Object> statistics = new HashMap<>();
            statistics.put("totalCount", 0);
            statistics.put("approvedCount", 0);
            statistics.put("rewardAmount", 0.0);
            statistics.put("punishmentAmount", 0.0);
            return statistics;
        }
        String currentUserId = corpMember.getMemberId();
        Map<String, Object> statistics = new HashMap<>();

        try {
            // 查询当前用户提交的所有记录
            List<Jx05dStaffIncentiveAndSanctionLo> allRecords = lambdaQuery()
                    .eq(Jx05dStaffIncentiveAndSanctionLo::getTheAuthor, currentUserId)
                    .list();

            // 查询所有记录（用于对比）
            List<Jx05dStaffIncentiveAndSanctionLo> allData = list();

            // 统计总订单数
            int totalCount = allRecords.size();

            // 统计已审核订单数
            int approvedCount = (int) allRecords.stream()
                    .filter(record -> "已审核".equals(record.getStatus()))
                    .count();

            // 统计奖励金额
            double rewardAmount = allRecords.stream()
                    .filter(record -> "奖励".equals(record.getTypeOfAward()) && "已审核".equals(record.getStatus()))
                    .mapToDouble(record -> {
                        try {
                            return Double.parseDouble(record.getAmount());
                        } catch (NumberFormatException e) {
                            return 0.0;
                        }
                    })
                    .sum();

            // 统计处罚金额
            double punishmentAmount = allRecords.stream()
                    .filter(record -> "处罚".equals(record.getTypeOfAward()) && "已审核".equals(record.getStatus()))
                    .mapToDouble(record -> {
                        try {
                            return Double.parseDouble(record.getAmount());
                        } catch (NumberFormatException e) {
                            return 0.0;
                        }
                    })
                    .sum();

            statistics.put("totalCount", totalCount);
            statistics.put("approvedCount", approvedCount);
            statistics.put("rewardAmount", rewardAmount);
            statistics.put("punishmentAmount", -punishmentAmount); // 处罚金额显示为负数

        } catch (Exception e) {
            // 如果获取用户ID失败，返回默认值
            System.out.println("统计过程中发生异常: " + e.getMessage());
            e.printStackTrace();
            statistics.put("totalCount", 0);
            statistics.put("approvedCount", 0);
            statistics.put("rewardAmount", 0.0);
            statistics.put("punishmentAmount", 0.0);
        }

        return statistics;
    }

    @Override
    public Map<String, Object> getStatisticsOverview(String startDate, String endDate) {
        Map<String, Object> overview = new HashMap<>();

        try {
            LambdaQueryWrapper<Jx05dStaffIncentiveAndSanctionLo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Jx05dStaffIncentiveAndSanctionLo::getStatus, "已审核");

            if (StringUtils.hasText(startDate)) {
                wrapper.ge(Jx05dStaffIncentiveAndSanctionLo::getDateOfRewardAndSanction, startDate);
            }
            if (StringUtils.hasText(endDate)) {
                wrapper.le(Jx05dStaffIncentiveAndSanctionLo::getDateOfRewardAndSanction, endDate);
            }

            List<Jx05dStaffIncentiveAndSanctionLo> records = list(wrapper);

            double rewardAmount = 0.0;
            double punishmentAmount = 0.0;

            for (Jx05dStaffIncentiveAndSanctionLo record : records) {
                try {
                    double amount = Double.parseDouble(record.getAmount());
                    if ("奖励".equals(record.getTypeOfAward())) {
                        rewardAmount += amount;
                    } else if ("处罚".equals(record.getTypeOfAward())) {
                        punishmentAmount += amount;
                    }
                } catch (NumberFormatException e) {
                    // 忽略无效金额
                }
            }

            overview.put("reward", rewardAmount);
            overview.put("punishment", punishmentAmount);
            overview.put("total", rewardAmount - punishmentAmount);

        } catch (Exception e) {
            overview.put("reward", 0.0);
            overview.put("punishment", 0.0);
            overview.put("total", 0.0);
        }

        return overview;
    }

    @Override
    public List<Map<String, Object>> getWorkshopStatistics(String startDate, String endDate) {
        List<Map<String, Object>> workshopStats = new ArrayList<>();

        try {
            LambdaQueryWrapper<Jx05dStaffIncentiveAndSanctionLo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Jx05dStaffIncentiveAndSanctionLo::getStatus, "已审核");

            if (StringUtils.hasText(startDate)) {
                wrapper.ge(Jx05dStaffIncentiveAndSanctionLo::getDateOfRewardAndSanction, startDate);
            }
            if (StringUtils.hasText(endDate)) {
                wrapper.le(Jx05dStaffIncentiveAndSanctionLo::getDateOfRewardAndSanction, endDate);
            }

            List<Jx05dStaffIncentiveAndSanctionLo> records = list(wrapper);

            // 按日期和车间分组统计
            Map<String, Map<String, Object>> dateWorkshopMap = new HashMap<>();

            for (Jx05dStaffIncentiveAndSanctionLo record : records) {
                String date = record.getDateOfRewardAndSanction();
                String workshop = record.getWorkshop();

                if (StringUtils.hasText(date) && StringUtils.hasText(workshop)) {
                    String key = date + "_" + workshop;

                    dateWorkshopMap.computeIfAbsent(key, k -> {
                        Map<String, Object> stats = new HashMap<>();
                        stats.put("date", date);
                        stats.put("workshop", workshop);
                        stats.put("reward", 0.0);
                        stats.put("punishment", 0.0);
                        stats.put("total", 0.0);
                        return stats;
                    });

                    try {
                        double amount = Double.parseDouble(record.getAmount());
                        Map<String, Object> stats = dateWorkshopMap.get(key);

                        if ("奖励".equals(record.getTypeOfAward())) {
                            stats.put("reward", (Double) stats.get("reward") + amount);
                        } else if ("处罚".equals(record.getTypeOfAward())) {
                            stats.put("punishment", (Double) stats.get("punishment") + amount);
                        }
                    } catch (NumberFormatException e) {
                    }
                }
            }

            // 计算合计
            for (Map<String, Object> stats : dateWorkshopMap.values()) {
                double reward = (Double) stats.get("reward");
                double punishment = (Double) stats.get("punishment");
                double total = reward - punishment;
                stats.put("total", total);
            }

            // 按日期倒序，然后按合计金额排序（数值越小越排前面）
            workshopStats = dateWorkshopMap.values().stream()
                    .sorted((a, b) -> {
                        // 首先按日期倒序
                        int dateCompare = ((String) b.get("date")).compareTo((String) a.get("date"));
                        if (dateCompare != 0) {
                            return dateCompare;
                        }
                        // 日期相同时按合计金额排序
                        return Double.compare((Double) a.get("total"), (Double) b.get("total"));
                    })
                    .collect(Collectors.toList());

        } catch (Exception e) {
        }

        return workshopStats;
    }

    @Override
    public List<Map<String, Object>> getTeamStatistics(String startDate, String endDate) {
        List<Map<String, Object>> teamStats = new ArrayList<>();

        try {
            LambdaQueryWrapper<Jx05dStaffIncentiveAndSanctionLo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Jx05dStaffIncentiveAndSanctionLo::getStatus, "已审核");

            if (StringUtils.hasText(startDate)) {
                wrapper.ge(Jx05dStaffIncentiveAndSanctionLo::getDateOfRewardAndSanction, startDate);
            }
            if (StringUtils.hasText(endDate)) {
                wrapper.le(Jx05dStaffIncentiveAndSanctionLo::getDateOfRewardAndSanction, endDate);
            }

            List<Jx05dStaffIncentiveAndSanctionLo> records = list(wrapper);

            // 按班组分组统计
            Map<String, Map<String, Object>> teamMap = new HashMap<>();

            for (Jx05dStaffIncentiveAndSanctionLo record : records) {
                String team = record.getClass5();
                if (StringUtils.hasText(team)) {
                    teamMap.computeIfAbsent(team, k -> {
                        Map<String, Object> stats = new HashMap<>();
                        stats.put("team", k);
                        stats.put("reward", 0.0);
                        stats.put("punishment", 0.0);
                        stats.put("total", 0.0);
                        return stats;
                    });

                    try {
                        double amount = Double.parseDouble(record.getAmount());
                        Map<String, Object> stats = teamMap.get(team);

                        if ("奖励".equals(record.getTypeOfAward())) {
                            stats.put("reward", (Double) stats.get("reward") + amount);
                        } else if ("处罚".equals(record.getTypeOfAward())) {
                            stats.put("punishment", (Double) stats.get("punishment") + amount);
                        }
                    } catch (NumberFormatException e) {

                    }
                }
            }

            // 计算合计并排序
            for (Map<String, Object> stats : teamMap.values()) {
                double reward = (Double) stats.get("reward");
                double punishment = (Double) stats.get("punishment");
                double total = reward - punishment;
                stats.put("total", total);
            }

            // 按合计金额倒序排列（数值越小越排前面）
            teamStats = teamMap.values().stream()
                    .sorted((a, b) -> Double.compare((Double) a.get("total"), (Double) b.get("total")))
                    .collect(Collectors.toList());

        } catch (Exception e) {

        }

        return teamStats;
    }

    @Override
    public List<Map<String, Object>> getEmployeeStatistics(String startDate, String endDate) {
        List<Map<String, Object>> employeeStats = new ArrayList<>();

        try {
            LambdaQueryWrapper<Jx05dStaffIncentiveAndSanctionLo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Jx05dStaffIncentiveAndSanctionLo::getStatus, "已审核");

            if (StringUtils.hasText(startDate)) {
                wrapper.ge(Jx05dStaffIncentiveAndSanctionLo::getDateOfRewardAndSanction, startDate);
            }
            if (StringUtils.hasText(endDate)) {
                wrapper.le(Jx05dStaffIncentiveAndSanctionLo::getDateOfRewardAndSanction, endDate);
            }

            List<Jx05dStaffIncentiveAndSanctionLo> records = list(wrapper);

            // 按员工分组统计
            Map<String, Map<String, Object>> employeeMap = new HashMap<>();

            for (Jx05dStaffIncentiveAndSanctionLo record : records) {
                String employeeName = record.getName();
                if (StringUtils.hasText(employeeName)) {
                    employeeMap.computeIfAbsent(employeeName, k -> {
                        Map<String, Object> stats = new HashMap<>();
                        stats.put("employee", k);
                        stats.put("total", 0.0);
                        return stats;
                    });

                    try {
                        double amount = Double.parseDouble(record.getAmount());
                        Map<String, Object> stats = employeeMap.get(employeeName);
                        double currentTotal = (Double) stats.get("total");

                        if ("奖励".equals(record.getTypeOfAward())) {
                            stats.put("total", currentTotal + amount);
                        } else if ("处罚".equals(record.getTypeOfAward())) {
                            stats.put("total", currentTotal - amount);
                        }
                    } catch (NumberFormatException e) {

                    }
                }
            }

            // 按合计金额倒序排列（数值越小越排前面）
            employeeStats = employeeMap.values().stream()
                    .sorted((a, b) -> Double.compare((Double) a.get("total"), (Double) b.get("total")))
                    .collect(Collectors.toList());

        } catch (Exception e) {

        }

        return employeeStats;
    }

    private CorpMember getCorpMember(){
        IPersonnelManagementDataSheetsService personnel = SpringUtil.getBean(IPersonnelManagementDataSheetsService.class);
        return personnel.getCorpMemberByLogin();
    }
}
